﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Kovan.Library.Utils;

namespace Kovan.Library.Extensions
{
    public static class UrlHelperExtensions
    {
        /// <summary>
        /// 缓存文件的版本
        /// </summary>
        private static Dictionary<string, string> FileVersion = new Dictionary<string, string>();
        /// <summary>
        /// 将虚拟（相对）路径转换为应用程序绝对路径
        /// </summary>
        /// <param name="url">已呈现的页的 URL</param>
        /// <param name="contentPath">内容的虚拟路径</param>
        /// <returns>应用程序绝对路径</returns>
        public static string Content2(this System.Web.Mvc.UrlHelper url, string contentPath)
        {
            // 防止低级错误
            if (url == null || HttpContext.Current == null) throw new Exception("非http请求不可调用此方法");
            if (string.IsNullOrEmpty(contentPath))
            {
                return url.Content(contentPath);
            }
            string lowerUrl = contentPath.ToLower();
            // 给 js 和 css 文件加上版本号
            if (lowerUrl.EndsWith(".js") || lowerUrl.EndsWith(".css"))
            {
                // 读取缓存的(本地的不缓存，以便调试)
                if (FileVersion.ContainsKey(lowerUrl) && IsLocal() == false)
                {
                    return FileVersion[lowerUrl];
                }
                // 将虚拟路径，转换为物理路径
                var path = HttpContext.Current.Server.MapPath(contentPath);
                var file = new System.IO.FileInfo(path);
                // 获取文件的最后修改时间
                var Version = file.LastWriteTime.ToString("yyyyMMddHHmmss");
                if (string.IsNullOrEmpty(Version))
                {
                    return url.Content(contentPath);
                }
                // 生成压缩的js文件
                if (lowerUrl.EndsWith(".js") && !lowerUrl.EndsWith(".min.js"))
                {
                    // 当配置了需要压缩js时，执行压缩。否则保持原文件
                    var needjsMin = Kovan.Library.Configuration.ConfigurationUtility.AppSettings<int>("JsMin", 0) == 1;
                    if (needjsMin)
                    {
                        // 保存原文件路径,压缩不成功时用原文件
                        var oldContent = contentPath;
                        try
                        {
                            var filePath = file.FullName;
                            // 生成压缩的js文件，结尾为".min.js"，前台访问的是压缩的版本
                            var minName = filePath.Substring(0, filePath.Length - 3) + ".min.js";
                            new JsMin().Minify(filePath, minName);
                            // 压缩成功，用压缩的js文件
                            contentPath = contentPath.Substring(0, contentPath.Length - 3) + ".min.js";
                        }
                        // 文件压缩会出现异常，这时候用回原文件
                        catch
                        {
                            contentPath = oldContent;
                        }
                    }
                }


                // 给文件加上版本号
                var newPath = url.Content(contentPath + "?" + Version);
                // 缓存起来
                FileVersion[lowerUrl] = newPath;
                return newPath;
            }
            return url.Content(contentPath);
        }

        /// <summary>
        /// 是否本地访问(本机及局域网内都返回true,否则返回false)
        /// </summary>
        /// <returns></returns>
        public static bool IsLocal()
        {
            // 防止低级错误
            if (HttpContext.Current == null) throw new Exception("非http请求不可调用此方法");
            var url = HttpContext.Current.Request.Url.OriginalString;
            if (!string.IsNullOrEmpty(url))
            {
                url = url.Trim().ToLower();
                // 本机或局域网的,判断为本地访问
                if (url.StartsWith("http://localhost") ||
                    url.StartsWith("http://127.0.0.") ||
                    url.StartsWith("http://192.168."))
                {
                    return true;
                }
            }
            return false;
        }
    }
}
